package A002_Obrazek;

/*
 * 003-FindImages
 * v.2.17
 */

import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;


public class _C_Filtruj implements _B_AlgorytmySzukania {
	
	private final int MAX_NR_FILTR = 23;
    // zmienne filtra
    private int wf; // zmienna szerokosc tablicy filtru
    private int hf; // zmienna wysokosc tablicy filtru
    private int filtr [][];
    private int sumaWartFiltru;
    
    private int wZ; // szerokosc tablicy zrodla dla kopi
    private int hZ; // szerokosc tablicy zrodla dla kopi
    public BufferedImage buffImg; // oryginalna tablica przekazana do klasy - przeliczana i kopiowana do _copybuffImgRGB 
	int [][] _copybuffImgRGB; // tablica do ktorej zostana wkopiowane przeliczone warosci z test1
	private BufferedImage buff; // Kopia buffimg
    
	public _C_Filtruj () throws Exception {
		Rectangle rec1 = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
        Robot robot = new Robot();
		buffImg = robot.createScreenCapture ( rec1 );
	    this.wZ = buffImg.getWidth(); // zmienna szerokosc tablicy zrodla dla kopi
	    this.hZ = buffImg.getHeight(); // zmienna szerokosc tablicy zrodla dla kopi
	}
	public _C_Filtruj (int xZKadr, int yZKadr, int wZKadr, int hZKadr) throws Exception{
		// inicjalizacja zmiennych dla zrodla i jego kopi
		Rectangle rec1 = new Rectangle(xZKadr, yZKadr, wZKadr, hZKadr);
        Robot robot = new Robot();
		buffImg = robot.createScreenCapture ( rec1 );
       	//buffImg = new BufferedImage (wZKadr, hZKadr ,BufferedImage.TYPE_INT_ARGB);
	    this.wZ = buffImg.getWidth(); // zmienna szerokosc tablicy zrodla dla kopi
	    this.hZ = buffImg.getHeight(); // zmienna szerokosc tablicy zrodla dla kopi
	    this._copybuffImgRGB = new int [this.wZ][this.hZ];
    	buff = new BufferedImage (wZ, hZ, BufferedImage.TYPE_INT_ARGB);
		}
	
	public _C_Filtruj (BufferedImage buffImg) throws Exception{
		// inicjalizacja zmiennych dla zrodla i jego kopi
	    this.wZ = buffImg.getWidth(); // zmienna szerokosc tablicy zrodla dla kopi
	    this.hZ = buffImg.getHeight(); // zmienna szerokosc tablicy zrodla dla kopi
       	this.buffImg = new BufferedImage (wZ, hZ, BufferedImage.TYPE_INT_ARGB);
       	this.buffImg = buffImg;
    	buff = new BufferedImage (wZ, hZ, BufferedImage.TYPE_INT_ARGB);
		}
	
	public BufferedImage UruchomFiltr (int nrfiltru){
		WybierzFiltr (nrfiltru);
		PrzeliczKomorke ();
		return this.buffImg;	
	}
	
	
	private final void WybierzFiltr (int nrfiltru){
		int f1 [][] = null;
		if (nrfiltru > MAX_NR_FILTR) {
			nrfiltru = 1;
			System.out.println("Filtr spoza zkresu " + nrfiltru);
		} else if (nrfiltru == 0) {
			nrfiltru = 0;
		}
		switch (nrfiltru){
		case 0: f1 = _B_AlgorytmySzukania.Alg_Piramidalny;
		break;
		case 1: f1 = _B_AlgorytmySzukania.Alg_Usredniajacy; 
		break;
		case 2: f1 = _B_AlgorytmySzukania.Alg_Kwadratowy; 
		break;
		case 3: f1 = _B_AlgorytmySzukania.Alg_Kolowy; 
		break;
		case 4: f1 = _B_AlgorytmySzukania.Alg_LP1; 
		break;
		case 5: f1 = _B_AlgorytmySzukania.Alg_LP2; 
		break;
		case 6: f1 = _B_AlgorytmySzukania.Alg_LP3; 
		break;
		case 7: f1 = _B_AlgorytmySzukania.Alg_Piramidalny;
		break;
		case 8: f1 = _B_AlgorytmySzukania.Alg_HP3; 
		break;
		case 9: f1 = _B_AlgorytmySzukania.Alg_Ukosny1; 
		break;
		case 10: f1 = _B_AlgorytmySzukania.Alg_Ukosny2; 
		break;
		case 11: f1 = _B_AlgorytmySzukania.Alg_Pionowy; 
		break;
		case 12: f1 = _B_AlgorytmySzukania.Alg_Poziomy; 
		break;
		case 13: f1 = _B_AlgorytmySzukania.Alg_Wschod; 
		break;
		case 14: f1 = _B_AlgorytmySzukania.Alg_EbonsceZachod; 
		break;
		case 15: f1 = _B_AlgorytmySzukania.Alg_EbonsPolnocnyZachod; 
		break;
		case 16: f1 = _B_AlgorytmySzukania.Alg_EbonsPolnoc; 
		break;
		case 17: f1 = _B_AlgorytmySzukania.Alg_EbonsPolnocnyWschod; 
		break;
		case 18: f1 = _B_AlgorytmySzukania.Alg_LAPL1; 
		break;
		case 19: f1 = _B_AlgorytmySzukania.Alg_LAPL2; 
		break;
		case 20: f1 = _B_AlgorytmySzukania.Alg_LAPL3; 
		break;
		case 21: f1 = _B_AlgorytmySzukania.Alg_LaplaceaUkosny; 
		break;
		case 22: f1 = _B_AlgorytmySzukania.Alg_LaplaceaPoziomy; 
		break;
		case 23: f1 = _B_AlgorytmySzukania.Alg_LaplaceaPionowy; 
		break;
		}
		//System.out.println ("Wybrales filtr nr " + nrfiltru ); 
		
		// inicjalizacja dla zmiennych filtru
		this.wf = f1.length;
		this.hf = f1[0].length;
		this.filtr = f1;
		int WartFiltru = 0;
		for (int a=0; a < f1.length; a++){
			for (int b = 0; b < f1[0].length; b++){
				WartFiltru += f1[a][b];
			}
		}
		this.sumaWartFiltru += (WartFiltru-1);
	}
	//========== formuoly =========
	private void PrzeliczKomorke (){
		//System.out.println("4. Przeliczam kkomorki bufferdimage buffImg i wpisuje do buff"); 
		int RelxZ = 0;
		int RelyZ = 0;
		int marginesfx = ((this.wf-1) / 2);
		int marginesfy = ((this.hf-1) / 2);
		int a = 0;//licznik
		
		for (int yZ = marginesfy ; yZ < (this.hZ-marginesfy) ; yZ++){
			for (int xZ = marginesfx ; xZ < (this.wZ-marginesfx) ; xZ++){
				
				double suma = 0;
				int alpha = 0;
				int red = 0;
				int green = 0;
				int blue = 0;
				
				int sumared = 0;
				int sumagreen = 0;
				int sumablue = 0;
				
				for (int yf = 0 ; yf < this.hf ; yf++){
					for (int xf = 0 ; xf < this.wf ; xf++){
						a++;
				    	RelxZ = xZ + (xf-marginesfx);
				    	RelyZ = yZ + (yf-marginesfy);
				    	
				    	int pixel = buffImg.getRGB(RelxZ, RelyZ);
				    	int wartfiltru = filtr[xf][yf];
				    	
				    	alpha = (pixel >> 24) & 0xff;
					 	red = (pixel >> 16) & 0xff;
					 	green = (pixel >> 8) & 0xff;
					 	blue = (pixel) & 0xff;
					 	
					 	red = red * wartfiltru;
					 	green = green * wartfiltru;
					 	blue = blue * wartfiltru;
					 	
					 	sumared += red;
					 	sumagreen += green;
					 	sumablue += blue;
				    }
				}
				
				if (sumaWartFiltru > 0){ // wyrownanie jasnosci
				 	if (sumared > 0) sumared /= sumaWartFiltru;
				 	if (sumagreen > 0) sumagreen /= sumaWartFiltru;
				 	if (sumablue > 0) sumablue /= sumaWartFiltru;
				}

			 	if (sumared > 255) sumared = 255;
			 	else if (sumared < 0) sumared = 0;
			 	if (sumagreen > 255) sumagreen = 255;
			 	else if (sumagreen < 0) sumagreen = 0;
			 	if (sumablue > 255) sumablue = 255;
			 	else if (sumablue < 0) sumablue = 0;
			 	
				int alpha2 = (alpha << 24);;
			 	int red2 = (sumared << 16); ;
			 	int green2 = (sumagreen << 8) ;
			 	int blue2 = (sumablue);
			 	int suma2 =  red2+green2+blue2+alpha2;
			 	
				buff.setRGB(xZ, yZ, suma2);
		    }
		}
		copybuffDObuffimg (this.buffImg, this.buff);
		//System.out.println("Szerokosc filtru " + wf + " Wyskosc " + hf);
		//System.out.println("Przeliczylem zrodlo Szerokosc " + wZ + " Wyskosc " + hZ);
		//System.out.println("Przeeliczylem kombinacji " + a + "\n\n");
	}
	
	public void ConvertGrayscale(){
		 BufferedImage img = new BufferedImage(wZ, hZ, BufferedImage.TYPE_BYTE_GRAY);
		    Graphics g = img.getGraphics();
		    g.drawImage(buffImg, 0, 0, null);
		    g.dispose();
			copybuffDObuffimg (this.buffImg, img);	
			}
	
	//kopiowanie bufera
	public BufferedImage copybuffDObuffimg (BufferedImage buffimg, BufferedImage buff){
		for (int yZ = 0 ; yZ < this.hZ ; yZ++){
			for (int xZ = 0 ; xZ < this.wZ ; xZ++){
				buffImg.setRGB(xZ, yZ, buff.getRGB(xZ, yZ)); 
			}
		}		
		return this.buffImg;
	}

    
    /*
    	//--------------TESTY------------
    	//-------------------------------
	    // 1. dla testu zapelnia buffImg wartosci 1
	    public void TestowoZapelnijbuffImg () {
	    	System.out.println("1. Zapelniam testowymi wartoscimi pusty  bufferdimage buffImg (czyli zrodlo)"); 
	    	int wart = -14277211;
	    	for (int a = 0; a < this.wZ; a++){
	        	for (int b = 0; b < this.hZ; b++){
	        		buffImg.setRGB(a, b, wart);
	        		//System.out.print (" " + _copybuffImgRGB[a][b]);
	        	}
	        	//System.out.println("");
	        }
	    }
	    
	    // 2. przepisuje wartosci z buffImg do bufferedImade buff
	    public void KopiujBufferedImage () {
	    	System.out.println("2. Zwracam  bufferdimage buff (kopie zrodla)"); 
	    	buff = new BufferedImage (wZ, hZ, BufferedImage.TYPE_INT_ARGB);
	    	for (int b = 0; b < this.hZ; b++){
	        	for (int a = 0; a < this.wZ; a++){
	        		buff.setRGB(a, b, buffImg.getRGB(a,b));
	        		//System.out.print (a + " " + b);
	        		//System.out.print (" "+ _copybuffImgRGB [a][b] + "\t");
	        	}
	        }
	    }
	    /*
	    // 3. drukuje testowy bufferedImade buffImg
	    public void DrukujbuffImg () {
	    	System.out.println("3. Drukuje zawartosc bufferdimage buffImg (zrodlo)");
	    	for (int b = 0; b < this.hZ; b++){
	        	for (int a = 0; a < this.wZ; a++){
	        		System.out.print(" "+buffImg.getRGB(a,b));
	        	}
	        	System.out.println(" ");
	        }
	    }*/
	    /*
	    // 4. drukuje testowy bufferedImade buff
	    public void Drukujbuff () {
	    	System.out.println("4. Drukuje zawartosc bufferdimage buff (kopii zrodla)");
	    	for (int b = 0; b < this.hZ; b++){
	        	for (int a = 0; a < this.wZ; a++){
	        		System.out.print(" "+buff.getRGB(a,b));
	        	}
	        	System.out.println(" ");
	        }
	    }*/
	    /*
	    // drukuje _copybuffImgRGB
    	public void DrukujcopyBuffImgRGB(){
	        for (int b = 0; b < this._copybuffImgRGB[0].length; b++){
	        	for (int a = 0; a < this._copybuffImgRGB.length ; a++){
	        		//System.out.print (a + " " + b);
	        		System.out.print (" "+ _copybuffImgRGB [a][b] + "\t");
	        	}
	        	System.out.println (" ");
	        }
	    }
	    */

}



